package com.alipay.util;

import com.alipay.config.AlipayConfig;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.httpclient.methods.multipart.FilePartSource;
import org.apache.commons.httpclient.methods.multipart.PartSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

/* *
 *类名：AlipayFunction
 *功能：支付宝接口公用函数类
 *详细：该类是请求、通知返回两个文件所调用的公用函数核心处理文件，不需要修改
 *版本：3.3
 *日期：2012-08-14
 *说明：
 *以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
 *该代码仅供学习和研究支付宝接口使用，只是提供一个参考。
 */

public class AlipayCore {
	private final static Logger logger=LoggerFactory.getLogger(AlipayCore.class);
    /** 
     * 除去数组中的空值和签名参数
     * @param sArray 签名参数组
     * @return 去掉空值与签名参数后的新签名参数组
     */
    public static Map<String, String> paraFilter(Map<String, String> sArray) {

        Map<String, String> result = new HashMap<String, String>();

        if (sArray == null || sArray.size() <= 0) {
            return result;
        }

        for (String key : sArray.keySet()) {
            String value = sArray.get(key);
            if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
                || key.equalsIgnoreCase("sign_type")) {
                continue;
            }
            result.put(key, value);
        }

        return result;
    }

	public static String CreatePreSignStr(Object o) throws  IllegalAccessException {
		ArrayList<String> list = new ArrayList<String>();
		Class cls = o.getClass();
		Field[] fields = cls.getDeclaredFields();
		for (Field f : fields) {
			f.setAccessible(true);
			if (f.get(o) != null && f.get(o) != "") {
				list.add(f.getName() + "=" + f.get(o) + "&");
			}
		}
		int size = list.size();
		String[] arrayToSort = list.toArray(new String[size]);
		Arrays.sort(arrayToSort);
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < size; i++) {
			sb.append(arrayToSort[i]);
		}
		String result = sb.toString();
		return result;
	}
    /** 
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createLinkString(Map<String, String> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        String prestr = "";
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);

            if (i == keys.size() - 1) {//拼接时，不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }
        return prestr;
    }
    
    /** 
     * 把数组所有元素按照固定参数排序，以“参数=参数值”的模式用“&”字符拼接成字符串
     * @param params 需要参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createLinkStringNoSort(Map<String, String> params) {
    	
    	//手机网站支付MD5签名固定参数排序，顺序参照文档说明
    	StringBuilder gotoSign_params = new StringBuilder();
    	gotoSign_params.append("service="+params.get("service"));
    	gotoSign_params.append("&v="+params.get("v"));
    	gotoSign_params.append("&sec_id="+params.get("sec_id"));
    	gotoSign_params.append("&notify_data="+params.get("notify_data"));
    	
    	return gotoSign_params.toString();
    }

    /** 
     * 写日志，方便测试（看网站需求，也可以改成把记录存入数据库）
     * @param sWord 要写入日志里的文本内容
     */
    public static void logResult(String sWord) {
        FileWriter writer = null;
        try {
            writer = new FileWriter(AlipayConfig.log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
            writer.write(sWord);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /** 
     * 生成文件摘要
     * @param strFilePath 文件路径
     * @param file_digest_type 摘要算法
     * @return 文件摘要结果
     */
    public static String getAbstract(String strFilePath, String file_digest_type) throws IOException {
        PartSource file = new FilePartSource(new File(strFilePath));
    	if(file_digest_type.equals("MD5")){
    		return DigestUtils.md5Hex(file.createInputStream());
    	}
    	else if(file_digest_type.equals("SHA")) {
    		return DigestUtils.sha256Hex(file.createInputStream());
    	}
    	else {
    		return "";
    	}
    }
    
    /**
	  * http请求对端方法,POST请求,支付宝接口：退款、扫码接口等使用,http post访问,使用ssl模式
	    * 
	    */
	public static String Httpssl_Post_Request(String urls,String parm) {
	        String inputLine = "";
	        HttpURLConnection urlConnection=null;
	        try {
//	        	new com.sun.net.ssl.internal.www.protocol.https.Handler(),由于在weblogic部署使用此模式
	            URL url = new URL(null,urls,new com.sun.net.ssl.internal.www.protocol.https.Handler());  
	            urlConnection = (HttpURLConnection) url.openConnection();
	            urlConnection.setDoOutput(true);
	            //设置连接主机超时（单位：毫秒）30秒
	            urlConnection.setConnectTimeout(30000);  
	            //设置从主机读取数据超时（单位：毫秒） 30秒
	            urlConnection.setReadTimeout(30000);  
	            urlConnection.setRequestProperty("Content-Length", Integer.toString(parm.length()));
	            urlConnection.setRequestProperty("Content-type", "application/x-www-form-urlencoded; text/html; charset="+AlipayConfig.input_charset);
	            urlConnection.setRequestMethod("POST");
	            OutputStream outputStream = urlConnection.getOutputStream();
	            OutputStreamWriter outputSW = new OutputStreamWriter(outputStream, AlipayConfig.input_charset);
	            outputSW.write(parm);
	            outputSW.flush();
	            outputSW.close();
	            BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection
	                .getInputStream(),AlipayConfig.input_charset));
	            logger.info("Httpsll_Post_Request----> in:"+in);
	            String context="";
	            while ( (context = (in.readLine())) != null) {
	            	inputLine+=context.trim();
	            }
	            logger.info("Httpsll_Post_Request---->inputLine:"+inputLine+"    in:"+in);
	            in.close();
	            in=null;
	            outputSW=null;
	        } catch (Exception e) {
	        	logger.debug("Httpsll_Post_Request---->e:"+e.getMessage());
	            e.printStackTrace();
	        }
	        finally{
	        	if(urlConnection!=null)
	        	urlConnection.disconnect();
	        	urlConnection=null;
	        	logger.debug("Httpsll_Post_Request---->urls:"+urls+" parm:"+parm);
	        }
	        return inputLine;

	    }



	/**
	  * http请求对端方法,POST请求,微信等接口：退款、扫码接口等使用,http post访问,使用 new URL(urls)
	    *
	    */
	public static String HttpUrl_Post_Request(String urls,String parm) {
	        String inputLine = "";
	        HttpURLConnection urlConnection=null;
	        try {
	        	URL url = new URL(urls);
	            urlConnection = (HttpURLConnection) url.openConnection();
	            urlConnection.setDoOutput(true);
	            //设置连接主机超时（单位：毫秒）30秒
	            urlConnection.setConnectTimeout(30000);
	            //设置从主机读取数据超时（单位：毫秒） 30秒
	            urlConnection.setReadTimeout(30000);
	            urlConnection.setRequestProperty("Content-Length", Integer.toString(parm.length()));
	            urlConnection.setRequestProperty("Content-type", "application/x-www-form-urlencoded; text/html; charset="+AlipayConfig.input_charset);
	            urlConnection.setRequestMethod("POST");
	            OutputStream outputStream = urlConnection.getOutputStream();
	            OutputStreamWriter outputSW = new OutputStreamWriter(outputStream, AlipayConfig.input_charset);
	            outputSW.write(parm);
	            outputSW.flush();
	            outputSW.close();
	            BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection
	                .getInputStream(),AlipayConfig.input_charset));
	            logger.info("HttpUrl_Post_Request----> in:"+in);
	            String context="";
	            while ( (context = (in.readLine())) != null) {
	            	inputLine+=context.trim();
	            }
	            logger.info("HttpUrl_Post_Request---->inputLine:"+inputLine+"    in:"+in);
	            in.close();
	            in=null;
	            outputSW=null;
	        } catch (Exception e) {
	        	logger.debug("HttpUrl_Post_Request---->e:"+e.getMessage());
	            e.printStackTrace();
	        }
	        finally{
	        	if(urlConnection!=null)
	        	urlConnection.disconnect();
	        	urlConnection=null;
	        	logger.debug("HttpUrl_Post_Request---->urls:"+urls+" parm:"+parm);
	        }
	        return inputLine;
	        
	    }
	
	/**
	  * http请求对端方法,POST请求,微信等接口：退款、扫码接口等使用,http post访问,使用 new URL(urls)
	    * 
	    */
	public static String HttpUrl_Get_Request(String urls) {
		URL url;
		try {
			url = new URL(urls);
			
			 // 设定连接的相关参数  
		      HttpURLConnection connection = (HttpURLConnection) url.openConnection();  
		        connection.setDoOutput(true);  
		       connection.setRequestMethod("GET");  
		       // 获取服务端的反馈  
		       String strLine = "";  
		        String strResponse = "";  
		       InputStream in = connection.getInputStream();
		       BufferedReader reader = new BufferedReader(new InputStreamReader(in,"GBK"));  
		       while ((strLine = reader.readLine()) != null){  
		          strResponse += strLine + "\n";  
		      }  
		       System.out.print(strResponse); 
		       return strResponse;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
